package com.redhipps.hips.client.widget;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Widget;
import com.redhipps.hips.client.command.CreateDoctorCommand;
import com.redhipps.hips.client.controller.EditCallback;
import com.redhipps.hips.client.controller.ModelEditDelegate;
import com.redhipps.hips.client.model.Context;
import com.redhipps.hips.client.model.Doctor;
import com.redhipps.hips.client.model.DoctorConstraint;
import com.redhipps.hips.client.model.PythonDatastoreKey;


public class DoctorList extends ModelList<Doctor> {

  private static String[] HEADERS = { "Name", "Login", "Days off",
      "Min shifts", "Max shifts", "Max night shifts", "Max consecutive days", "Edit" };

  private List<DoctorConstraint> doctorConstraints;
  private Map<PythonDatastoreKey, ClickListener> doctorKeyToEditListener;
  private Map<PythonDatastoreKey, DoctorConstraint> doctorKeyToConstraint;

  public DoctorList(Context ctx, List<Doctor> values) {
    super(ctx, values);
    setEditingDelegate(new DoctorListEditDelegate());
    refresh();
  }

  @Deprecated  // Use a doctor constraint list instead
  public void setDoctorConstraints(
      List<DoctorConstraint> doctorConstraints, List<ClickListener> editListeners) {
    this.doctorConstraints = doctorConstraints;
    doctorKeyToConstraint = new HashMap<PythonDatastoreKey, DoctorConstraint>();
    doctorKeyToEditListener = new HashMap<PythonDatastoreKey, ClickListener>();
    for (int i = 0; i < doctorConstraints.size(); i++) {
      DoctorConstraint doctorConstraint = this.doctorConstraints.get(i);
      ClickListener constraintListener = editListeners.get(i);
      PythonDatastoreKey doctorKey = doctorConstraint.getDoctorRef();
      doctorKeyToConstraint.put(doctorKey, doctorConstraint);
      doctorKeyToEditListener.put(doctorKey, constraintListener);
    }
    refresh();
  }
  
  @Override
  protected Object[] headers() {
    return HEADERS;
  }

  @Override
  protected Object[] writeModel(final Doctor model, int row) {
    Object[] values = new Object[8];
    Hyperlink hyperlink = new Hyperlink(model.getName(), "doctorList");
    hyperlink.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        context().pushDoctor(model);
      }
    });
    values[0] = hyperlink;
    values[1] = model.getLogin();
    DoctorConstraint constraint = doctorKeyToConstraint != null ?
        doctorKeyToConstraint.get(model.key()) : null;
    if (constraint != null) {
      StringBuilder b = new StringBuilder();
      List<?> listValue = constraint.getDaysOff();
      for (int i = 0; i < listValue.size(); i++) {
        b.append(listValue.get(i));
        if (i < listValue.size() - 1) {
          b.append(", ");
        }
      }
      values[2] = b.toString();
      values[3] = constraint.getMinShifts();
      values[4] = constraint.getMaxShifts();
      values[5] = constraint.getMaxNightShifts();
      values[6] = constraint.getMaxConsecutiveDays();
    } else {
      values[3] = model.getMinShifts();
      values[4] = model.getMaxShifts();
      values[5] = model.getMaxNightShifts();
      values[6] = model.getMaxConsecutiveDays();
    }
    if (doctorKeyToEditListener != null) {
      Button editButton = new Button("Edit...");
      ClickListener l = doctorKeyToEditListener.get(model.key());
      editButton.addClickListener(l);
      values[7] = editButton;
    }
    return values;
  }

  private static class DoctorListEditDelegate implements ModelEditDelegate<Doctor> {

    public void createModel(Context context, EditCallback<Doctor> callback) {
      invokeWithEditCallback(new CreateDoctorCommand(), context, callback);
    }

    public void deleteModel(Context context, Doctor model, EditCallback<Doctor> callback) {
      // TODO Auto-generated method stub   
    }

    public void editModel(Context context, Doctor model, EditCallback<Doctor> callback) {
      // TODO Auto-generated method stub
    }
    
  }
}
